
//
//  MSService.m
//  Oldies Hits
//
//  Created by Diep Duong on 12/2/11.
//  Copyright (c) 2011 GNT Vietnam. All rights reserved.
#import "UIApplicationExt.h"
#import "MBUtils.h"
#import "MBService.h"
#import "ASIFormDataRequest.h"
#import "JSON.h"
#import "CJSONDeserializer.h"


NSString *MBErrorDomain = @"ios.oldieshits.japan";

@interface MBService ()

- (NSString *)joinParameters:(NSDictionary *)params;
- (void)processData:(NSData *)data;
- (BOOL)doRequestWithURL:(NSString *)urlString params:(NSDictionary *)pValues;
- (BOOL)doRequestWithURL:(NSString *)urlString params:(NSDictionary *)pValues isPost:(BOOL)isPost;
- (BOOL)doRequestWithURL:(NSString *)urlString params:(NSDictionary *)pValues isPost:(BOOL)isPost headers:(NSDictionary *)headers;
- (void)stopTimerIfNeeded;
- (void)processError:(NSError *)error;
@end

@implementation MBService

@synthesize action			= _action;
@synthesize delegate		= _delegate;
@synthesize connecting		= _connecting;
@synthesize connection		= _connection;
@synthesize buffer			= _buffer;
@synthesize canShowAlert    = _canShowAlert;
@synthesize canShowLoading  = _canShowLoading;
@synthesize timeout         = _timeout;

- (id)init 
{ 
    self = [super init];
    if (self) {
        self.connecting = FALSE;
        self.buffer = nil;        
        self.delegate = nil;
        self.action = ActionTypeNone;
		self.canShowAlert = TRUE;
        self.canShowLoading = TRUE;
        self.timeout = 10;
    }
    return self;
}

#pragma mark MBServiceProcessing

- (void)reset 
{
    @synchronized(self)
    {
        [self stopTimerIfNeeded];
        if (self.connecting) 
        {
            if (self.canShowLoading) 
            {
//                [[UIApplication sharedApplication] showNetworkActivityIndicatorVisible:FALSE];
            }
        }
        
        self.connecting = FALSE;
        self.action = ActionTypeNone;
        if (_connection) 
        {
            [_connection cancel];
            [_connection release];
            _connection = nil;
        }    
        if (_buffer) 
        {
            [_buffer release];
            _buffer = nil;
        }
        if (_asiRequest) 
        {
            [_asiRequest cancel];
            [_asiRequest release];
            _asiRequest = nil;
        }
    }
}

- (void)stop 
{
    self.delegate = nil;
    [self reset];
}

- (void)stopTimerIfNeeded 
{
    if (_timer) 
    {
        [_timer invalidate];
        [_timer release];
        _timer = nil;
    }
}

- (void)startTimer 
{
    _timer = [[NSTimer timerWithTimeInterval:self.timeout
                                      target:self
                                    selector:@selector(didTimeOut)
                                    userInfo:nil
                                     repeats:NO] retain];
    [[NSRunLoop mainRunLoop] addTimer:_timer 
                              forMode:NSDefaultRunLoopMode];
}

- (void)didTimeOut 
{
    if (self.connecting) 
    {
        [self processError:mb_err(408)]; // time out
    }
}

- (BOOL)doRequestWithURL:(NSString *)urlString params:(NSDictionary *)pValues isPost:(BOOL)isPost headers:(NSDictionary *)headers
{
    [self stopTimerIfNeeded];
    
    NSString *paramsString = [self joinParameters:pValues];  
	NSString *newURL;
	if(pValues)
		newURL = (isPost ? urlString : [NSString stringWithFormat:@"%@?%@", urlString, paramsString]);
	else 
    {
		newURL = (isPost ? urlString : [NSString stringWithFormat:@"%@", urlString]);
	}
    
    //printf([[NSString stringWithFormat:@"params: %@ \n and URL: %@", paramsString, newURL] UTF8String]);
//    DLog(@"req:%@", newURL);
    
    if (_buffer) 
    {
        [_buffer release];
        _buffer = nil;
    }
    if (_connection)
    {
        [_connection cancel];
        [_connection release];
        _connection = nil;
    }
    
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:newURL]
                                                                cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                            timeoutInterval:self.timeout];    
    [request setHTTPMethod:(isPost) ? @"POST" : @"GET"];
    
    if (isPost) 
    {
        NSData *data = [[NSData alloc] initWithBytes:[paramsString UTF8String] length:[paramsString length]];    
        [request setHTTPBody:data];
        [data release];
    }
    
    // set header here   
    
  	_buffer = [[NSMutableData alloc] init];
    _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [request release];
    
    if (_connection) 
    {
        _connecting = TRUE;
        if (self.canShowLoading)
        {
            [[UIApplication sharedApplication] showNetworkActivityIndicatorVisible:TRUE];
        }
        [self startTimer];
        return TRUE;
    }
    return FALSE;
}

- (BOOL)doRequestWithURL:(NSString *)urlString params:(NSDictionary *)params isPost:(BOOL)isPost 
{
    return [self doRequestWithURL:urlString params:params isPost:isPost headers:nil];
}

- (BOOL)doRequestWithURL:(NSString *)urlString params:(NSDictionary *)params 
{
    return [self doRequestWithURL:urlString params:params isPost:FALSE headers:nil];
}

- (BOOL)doASIRequestWithURL:(NSString *)urlString params:(NSDictionary *)pValues 
{
    NSURL *url = [NSURL URLWithString:urlString];
    if (!url) 
    {
        return FALSE;
    }
    self.connecting = YES;
    
    _asiRequest = [[ASIFormDataRequest requestWithURL:url] retain];
    _asiRequest.postFormat = ASIURLEncodedPostFormat;
    _asiRequest.delegate = self;
    _asiRequest.timeOutSeconds = self.timeout;
    [_asiRequest setPersistentConnectionTimeoutSeconds:1];
    [_asiRequest setValidatesSecureCertificate:NO];
    [_asiRequest setDidFailSelector:@selector(asiDidFailWithError:)];
    [_asiRequest setDidFinishSelector:@selector(asiDidFinished:)];
    
    if (pValues)
    {
        NSArray *keys = [pValues allKeys];
        for (NSString *key in keys) {
            if ([key hasPrefix:@"file_"]) 
            {
                NSDictionary *fileInfo = [pValues objectForKey:key];
                [_asiRequest setFile:[fileInfo objectForKey:@"photo"] 
                        withFileName:@"mm-upload.jpg"
                      andContentType:@"image/jpg"
                              forKey:@"photo"];
            } 
            else if ([key hasPrefix:@"avatar_"]) 
            {
                NSDictionary *fileInfo = [pValues objectForKey:key];
                [_asiRequest setFile:[fileInfo objectForKey:@"datafile"] 
                        withFileName:@"avatar.png"
                      andContentType:@"image/png"
                              forKey:@"datafile"];
			} 
            else if ([key hasPrefix:@"backup_"]) 
            {
                NSDictionary *fileInfo = [pValues objectForKey:key];
                [_asiRequest setFile:[fileInfo objectForKey:@"backup_file"] 
                        withFileName:[fileInfo objectForKey:@"filename"]
                      andContentType:@"application/octet-stream"
                              forKey:@"backup_file"];
            }
            else 
            {
                [_asiRequest setPostValue:[pValues objectForKey:key] forKey:key];
            }
        }
    }
    [[UIApplication sharedApplication] showNetworkActivityIndicatorVisible:TRUE];
    [_asiRequest startAsynchronous];
    return TRUE;
}

- (void)asiDidFailWithError:(ASIHTTPRequest *)theRequest 
{
    [self processError:[theRequest error]];
}

- (void)asiDidFinished:(ASIHTTPRequest *)theRequest 
{   
    if (self.delegate) 
    {
        [self processData:[theRequest responseData]];
    }
    [self reset];
}

- (void)processError:(NSError *)error
{
    @synchronized(self)
    {
        @try 
        {
            NSLog(@"Request failed! Error:(%d) %@", error.code, [error localizedDescription]);
            [self reset];
            
            if (!_delegate)
                return;
            
            if (self.canShowAlert)
            {                
//                [MainController showNetworkError];
            }
            
            SEL sel = @selector(mbService:didFailWithError:);
            if (_delegate && [_delegate respondsToSelector:sel]) 
            {
                [_delegate performSelector:sel withObject:self withObject:mb_err([error code])];
            }
        } 
        @catch (NSException *ex) 
        {
            NSLog(@"processError:%@", [ex reason]);
        }
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSHTTPURLResponse *)response
{
    [self stopTimerIfNeeded];
    [_buffer setLength:0];

    
    int code = [response statusCode];
    if (code == 404)
    {
        NSString *emptyXml = @"";
        [_buffer appendData:[emptyXml dataUsingEncoding:NSUTF8StringEncoding]];
        [self processData:_buffer];
    }
    else if (code != 200)
    {
        [self processError:mb_err(code)];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
    [_buffer appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{    
    [self processError:error];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{  
    [self processData:_buffer];
}

- (NSString *)joinParameters:(NSDictionary *)params 
{
    NSString *paramsString = @"";
    if (params) 
    {
        NSArray *keys = [params allKeys];
		int c = [keys count];
		int i = 0;
		
        while (i < c) 
        {
			NSString *k = [keys objectAtIndex:i];
            NSString *v = [params valueForKey:k];
            if (k && v) 
            {
                
                v = [MBUtils URLEncode:v];
                paramsString = [paramsString stringByAppendingFormat:@"%@=%@", k, v];
                
            }
			i++;
			if (i >= c)
				break;
			paramsString = [paramsString stringByAppendingString:@"&"];
		}
    }
    return paramsString;
}

+ (void)showErrorNetwork 
{
//    MessageBox *box = [MessageBox sharedMessageBox];
//    [box showBoxWithTitle:LocStr(@"AlertTitleErrorNetwork")
//                  message:LocStr(@"AlertMsgErrorNetwork") 
//                 delegate:nil 
//        cancelButtonTitle:LocStr(@"OK")
//        otherButtonTitles:nil];
}
//Tamle
/*------------------------------------------------------------------------------------
 Method: get url of company info  from server
 ------------------------------------------------------------------------------------*/
- (void)getUserPoint
{
    self.action = ActionTypeGetUserPoint;
    NSString * url = [NSString stringWithFormat:@"%@/reward/music/jp/getpoint?",API_MUSIC];
    NSMutableDictionary *params = [[NSMutableDictionary alloc]init];
    [params setObject:@"member_id" forKey:@"12345"];
    [self doRequestWithURL:url params:params isPost:NO];
    [params release];
}


- (void)processData:(NSData *)data 
{
    //NSLog(@"%@", [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]);
   
    if (self.delegate == nil) 
    {
        [self reset];
        return;
    }
    
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    int act = self.action;
    NSData *buff = data;
    @try 
    {
        
        switch(act)
        {
            case ActionTypeGetUserPoint: 
            {
                CJSONDeserializer *jsonDeserializer = [CJSONDeserializer deserializer];
                NSDictionary *resultsDictionary = (NSDictionary *)[jsonDeserializer deserializeAsDictionary:buff error:nil];
                
                NSString *status = @"Fail";
                if (resultsDictionary)
                {
                    status = [resultsDictionary objectForKey:@"status"];
                }

                if ([status isEqualToString: @"success"]) 
                {
                    SEL sel = @selector(mbServiceGetUserPointSucceed:responses:);
                    NSString *point = [resultsDictionary objectForKey:@"point"];
                    if ([_delegate respondsToSelector:sel]) {
                        [_delegate performSelector:sel withObject:self withObject:point];
                    }
                } 
                else
                {
                    SEL sel = @selector(mbServiceGetUserPointFailed:);
                    if ([_delegate respondsToSelector:sel]) 
                    {
                        [_delegate performSelector:sel withObject:self];
                    }
                }
                
                break;
            }
           
        }
        
    } 
    @catch (NSException *ex) 
    {        
    } 
    
    [pool drain];
    [self reset];
}

- (void)dealloc 
{
    [self stop];
    [super dealloc];
}
@end
